//
//  NSString+Category.m
//  LinHuaQianBusiness
//
//  Created by zhangsong on 16/8/16.
//  Copyright © 2016年 Shuang Qian Online Payment Company. All rights reserved.
//

#import "NSString+Category.h"
#import<CommonCrypto/CommonDigest.h>

@implementation NSString (Category)

- (NSInteger)byteLength {
    //拿到所有str的length长度（包括中文英文..都算为1个字符）
    NSUInteger len = self.length;
    //汉字字符集
    NSString* pattern = @"[\u4e00-\u9fa5]";
    //正则表达式筛选条件
    NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:nil];
    //计算中文字符的个数
    NSInteger numMatch = [regex numberOfMatchesInString:self options:NSMatchingReportProgress range:NSMakeRange(0, len)];
    //len已经把中文算进去了，中文少的一个字符通过numMatch个数来补充，效果就是中文2个字符，英文1个字符
    return len + numMatch;
}

- (BOOL)hasChinese {
    //拿到所有str的length长度（包括中文英文..都算为1个字符）
    NSUInteger len = self.length;
    //汉字字符集
    NSString* pattern = @"[\u4e00-\u9fa5]";
    //正则表达式筛选条件
    NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:nil];
    //计算中文字符的个数
    NSInteger numMatch = [regex numberOfMatchesInString:self options:NSMatchingReportProgress range:NSMakeRange(0, len)];
   
    return numMatch > 0;
}

- (BOOL)stringContainsEmoji {
    // 过滤所有表情。returnValue为NO表示不含有表情，YES表示含有表情
    __block BOOL returnValue = NO;
    [self enumerateSubstringsInRange:NSMakeRange(0, [self length]) options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
        
        const unichar hs = [substring characterAtIndex:0];
        // surrogate pair
        if (0xd800 <= hs && hs <= 0xdbff) {
            if (substring.length > 1) {
                const unichar ls = [substring characterAtIndex:1];
                const int uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
                if (0x1d000 <= uc && uc <= 0x1f77f) {
                    returnValue = YES;
                }
            }
        } else if (substring.length > 1) {
            const unichar ls = [substring characterAtIndex:1];
            if (ls == 0x20e3) {
                returnValue = YES;
            }
        } else {
            // non surrogate
            if (0x2100 <= hs && hs <= 0x27ff) {
                returnValue = YES;
            } else if (0x2B05 <= hs && hs <= 0x2b07) {
                returnValue = YES;
            } else if (0x2934 <= hs && hs <= 0x2935) {
                returnValue = YES;
            } else if (0x3297 <= hs && hs <= 0x3299) {
                returnValue = YES;
            } else if (hs == 0xa9 || hs == 0xae || hs == 0x303d || hs == 0x3030 || hs == 0x2b55 || hs == 0x2b1c || hs == 0x2b1b || hs == 0x2b50) {
                returnValue = YES;
            }
        }
    }];
    return returnValue;
}


- (NSMutableAttributedString *)modifyDigitalColor:(UIColor *)color normalColor:(UIColor *)normalColor;
{
    NSRegularExpression *regular = [NSRegularExpression regularExpressionWithPattern:@"([0-9]\\d*\\.?\\d*)" options:0 error:NULL];
    
    NSArray<NSTextCheckingResult *> *ranges = [regular matchesInString:self options:0 range:NSMakeRange(0, [self length])];
    
    NSMutableAttributedString *attStr = [[NSMutableAttributedString alloc] initWithString:self attributes:@{NSForegroundColorAttributeName : normalColor}];
    
    for (int i = 0; i < ranges.count; i++) {
        [attStr setAttributes:@{NSForegroundColorAttributeName : color} range:ranges[i].range];
    }
    return attStr;
}
// 判断手机号
- (BOOL)checkPhoneNumFunction
{
    NSString *regex2 = @"^[1][3,4,5,7,8,9][\\d]{9}$";
    NSPredicate *pred2 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex2];
    BOOL isMatch2 = [pred2 evaluateWithObject:self];
    return isMatch2;
}
// 判断固话
- (BOOL)checkFixedPhoneNumber {
    //验证输入的固话中不带 "-"符号
    NSString * strNum1 = @"^(0[0-9]{2,3})?([2-9][0-9]{6,7})+(-[0-9]{1,4})?$|(^(13[0-9]|15[0|3|6|7|8|9]|18[8|9])\\d{8}$)";
    NSPredicate *checktest1 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", strNum1];
    BOOL cheak1 = [checktest1 evaluateWithObject:self];
    return cheak1;
    
//    //验证输入的固话中带 "-"符号
//    NSString * strNum2 = @"^(0[0-9]{2,3}-)?([2-9][0-9]{6,7})+(-[0-9]{1,4})?$|(^(13[0-9]|15[0|3|6|7|8|9]|18[8|9])\\d{8}$)";
//    NSPredicate *checktest2 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", strNum2];
//    BOOL cheak2 = [checktest2 evaluateWithObject:self];
    
}
//身份证号
- (BOOL)CheckIsIdentityCard
{
    //判断是否为空
    if (self==nil||self.length <= 0) {
        return NO;
    }
    //判断是否是18位，末尾是否是x
    NSString *regex2 = @"^(\\d{14}|\\d{17})(\\d|[xX])$";
    NSPredicate *identityCardPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex2];
    if(![identityCardPredicate evaluateWithObject:self]){
        return NO;
    }
    //判断生日是否合法
    NSRange range = NSMakeRange(6,8);
    NSString *datestr = [self substringWithRange:range];
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat : @"yyyyMMdd"];
    if([formatter dateFromString:datestr]==nil){
        return NO;
    }
    
    //判断校验位
    if(self.length==18)
    {
        NSArray *idCardWi= @[ @"7", @"9", @"10", @"5", @"8", @"4", @"2", @"1", @"6", @"3", @"7", @"9", @"10", @"5", @"8", @"4", @"2" ]; //将前17位加权因子保存在数组里
        NSArray * idCardY=@[ @"1", @"0", @"10", @"9", @"8", @"7", @"6", @"5", @"4", @"3", @"2" ]; //这是除以11后，可能产生的11位余数、验证码，也保存成数组
        int idCardWiSum=0; //用来保存前17位各自乖以加权因子后的总和
        for(int i=0;i<17;i++){
            idCardWiSum+=[[self substringWithRange:NSMakeRange(i,1)] intValue]*[idCardWi[i] intValue];
        }
        
        int idCardMod=idCardWiSum%11;//计算出校验码所在数组的位置
        NSString *idCardLast=[self substringWithRange:NSMakeRange(17,1)];//得到最后一位身份证号码
        
        //如果等于2，则说明校验码是10，身份证号码最后一位应该是X
        if(idCardMod==2){
            if([idCardLast isEqualToString:@"X"]||[idCardLast isEqualToString:@"x"]){
                return YES;
            }else{
                return NO;
            }
        }else{
            //用计算出的验证码与最后一位身份证号码匹配，如果一致，说明通过，否则是无效的身份证号码
            if([idCardLast intValue]==[idCardY[idCardMod] intValue]){
                return YES;
            }else{
                return NO;
            }
        }
    }
    return NO;
}
#pragma mark - 判断是否为金额输入格式
-(BOOL)isValidateMoneying{
    //正在输入的金额必须以数字开头
    
    //没有小数点
    NSString * money1=@"^[0-9]{1}";
    NSPredicate *regextestmoney1=[NSPredicate predicateWithFormat:@"SELF MATCHES %@", money1];
    
    NSString * money11=@"^[1-9][0-9]+$";
    NSPredicate *regextestmoney11=[NSPredicate predicateWithFormat:@"SELF MATCHES %@", money11];
    
    //有小数点
    NSString * money2=@"^[0-9]{1}\\.{0,1}";
    NSPredicate *regextestmoney2=[NSPredicate predicateWithFormat:@"SELF MATCHES %@", money2];
    
    NSString * money21=@"^[0-9]{1}\\.{1}[0-9]{1,2}";
    NSPredicate *regextestmoney21=[NSPredicate predicateWithFormat:@"SELF MATCHES %@", money21];
    
    
    NSString * money3=@"^[1-9]{1}[0-9]+\\.{1}[0-9]{1,2}";
    NSPredicate *regextestmoney3=[NSPredicate predicateWithFormat:@"SELF MATCHES %@", money3];
    
    NSString * money31=@"^[1-9]{1}[0-9]+\\.{0,1}";
    NSPredicate *regextestmoney31=[NSPredicate predicateWithFormat:@"SELF MATCHES %@", money31];
    
    
    if ([self isEmptyString]||[regextestmoney1 evaluateWithObject:self]||[regextestmoney2 evaluateWithObject:self] ||[regextestmoney21 evaluateWithObject:self]||[regextestmoney3 evaluateWithObject:self]||[regextestmoney11 evaluateWithObject:self]||[regextestmoney31 evaluateWithObject:self])
    {
        return YES;
    }else{
        return NO;
    }
    
}
#pragma mark 是否空字符串
- (BOOL)isEmptyString
{
    return (!self || self.length < 1 || self == nil  || [self isEqualToString:@"(null)"] || [self isEqualToString:@"<null>"] || [self isEqualToString:@"null"] || [self isEqual:[NSNull class]]);
}
// 验证邮箱格式
-(BOOL)cheakValidateEmail {
    NSString *emailRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
    NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];
    return [emailTest evaluateWithObject:self];
}
- (BOOL)isPureInt:(NSString *)string {
    NSScanner *scan = [NSScanner scannerWithString:string];

    int value;

    return [scan scanInt:&value] && [scan isAtEnd];

}
//取出字符串中的数字字符串
-(NSString *)takeOutStringNumber
{
    NSCharacterSet* nonDigits = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
    NSString *remainSecond = [self stringByTrimmingCharactersInSet:nonDigits] ;
    return remainSecond;
}

// label 自适应宽度
- (CGSize)sizeForNoticeFont:(UIFont*)font withHeight:(CGFloat)maxHeight
{
    CGSize maxSize = CGSizeMake(CGFLOAT_MAX, maxHeight);
    
    CGSize textSize = CGSizeZero;
    
    // 多行必需使用NSStringDrawingUsesLineFragmentOrigin，网上有人说不是用NSStringDrawingUsesFontLeading计算结果不对
    NSStringDrawingOptions opts = NSStringDrawingUsesLineFragmentOrigin |
    NSStringDrawingUsesFontLeading;
    
    NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
    [style setLineBreakMode:NSLineBreakByCharWrapping];
    
    NSDictionary *attributes = @{NSFontAttributeName : font, NSParagraphStyleAttributeName : style };
    
    CGRect rect = [self boundingRectWithSize:maxSize
                                     options:opts
                                  attributes:attributes
                                     context:nil];
    textSize = rect.size;
    
    return textSize;
}
// label 自适应高度
- (CGSize)sizeForNoticeFont:(UIFont*)font withWdith:(CGFloat)maxWdith
{
    CGSize maxSize = CGSizeMake(maxWdith, CGFLOAT_MAX);
    
    CGSize textSize = CGSizeZero;
    
    // 多行必需使用NSStringDrawingUsesLineFragmentOrigin，网上有人说不是用NSStringDrawingUsesFontLeading计算结果不对
    NSStringDrawingOptions opts = NSStringDrawingUsesLineFragmentOrigin |
    NSStringDrawingUsesFontLeading;
    
    NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
    [style setLineBreakMode:NSLineBreakByCharWrapping];
    
    NSDictionary *attributes = @{ NSFontAttributeName : font, NSParagraphStyleAttributeName : style };
    
    CGRect rect = [self boundingRectWithSize:maxSize
                                     options:opts
                                  attributes:attributes
                                     context:nil];
    textSize = rect.size;
    
    return textSize;
}

//判断字符串中包含数字和字母的几种情况
-(int)checkIsHaveNumAndLetter{
    
    //数字条件
    NSRegularExpression *tNumRegularExpression = [NSRegularExpression regularExpressionWithPattern:@"[0-9]" options:NSRegularExpressionCaseInsensitive error:nil];
    
    //符合数字条件的有几个字节
    NSUInteger tNumMatchCount = [tNumRegularExpression numberOfMatchesInString:self
                                                                       options:NSMatchingReportProgress
                                                                         range:NSMakeRange(0, self.length)];
    
    //英文字条件
    NSRegularExpression *tLetterRegularExpression = [NSRegularExpression regularExpressionWithPattern:@"[A-Za-z]" options:NSRegularExpressionCaseInsensitive error:nil];
    
    //符合英文字条件的有几个字节
    NSUInteger tLetterMatchCount = [tLetterRegularExpression numberOfMatchesInString:self options:NSMatchingReportProgress range:NSMakeRange(0, self.length)];
    
    if (tNumMatchCount == self.length) {
        //全部符合数字，表示沒有英文
        return 1;
    } else if (tLetterMatchCount == self.length) {
        //全部符合英文，表示沒有数字
        return 2;
    } else if (tNumMatchCount + tLetterMatchCount == self.length) {
        //符合英文和符合数字条件的相加等于密码长度
        return 3;
    } else {
        return 4;
        //可能包含标点符号的情況，或是包含非英文的文字，这里再依照需求详细判断想呈现的错误
    }
    
}

- (BOOL)CheckIsALBNumber {
    
    //数字条件
    NSRegularExpression *tNumRegularExpression = [NSRegularExpression regularExpressionWithPattern:@"[0-9]" options:NSRegularExpressionCaseInsensitive error:nil];
    //符合数字条件的有几个字节
    NSUInteger tNumMatchCount = [tNumRegularExpression numberOfMatchesInString:self
                                                                       options:NSMatchingReportProgress
                                                                         range:NSMakeRange(0, self.length)];
    if (tNumMatchCount == self.length) {
        //全部符合数字
        return YES;
    }
    return NO;
}


//手机号、银行卡、身份证脱敏处理
-(NSString *)phoneTransform;
{
    if (self.length > 7) {
        return [self stringByReplacingCharactersInRange:NSMakeRange(3, 4) withString:@"****"];
    }else{
        return self;
    }
    
}
-(NSString *)bankCardTransform;
{
    if (self.length > 16) {
        return [self stringByReplacingCharactersInRange:NSMakeRange(6, self.length-10) withString:@"****"];
    }else{
        return self;
    }
}
-(NSString *)IDCardTransform;
{
    if (self.length == 18) {
        return [self stringByReplacingCharactersInRange:NSMakeRange(1, 16) withString:@"****************"];
    }else{
        return self;
    }
}

//金钱每三位加一个逗号，经过封装的一个方法直接调用即可，传一个你需要加，号的字符串就好了
+(NSString *)countNumAndChangeformat:(NSString *)num
{
    if([num rangeOfString:@"."].location !=NSNotFound) //这个判断是判断有没有小数点如果有小数点，需特别处理，经过处理再拼接起来
     {
        NSString *losttotal = [NSString stringWithFormat:@"%.2f",[num floatValue]];//小数点后只保留两位
        NSArray *array = [losttotal componentsSeparatedByString:@"."];
        //小数点前:array[0]
        //小数点后:array[1]
        int count = 0;
        num = array[0];
        long long int a = num.longLongValue;
        while (a != 0)
        {
            count++;
            a /= 10;
        }
        NSMutableString *string = [NSMutableString stringWithString:num];
        NSMutableString *newstring = [NSMutableString string];
        while (count > 3) {
            count -= 3;
            NSRange rang = NSMakeRange(string.length - 3, 3);
            NSString *str = [string substringWithRange:rang];
            [newstring insertString:str atIndex:0];
            [newstring insertString:@"," atIndex:0];
            [string deleteCharactersInRange:rang];
        }
        [newstring insertString:string atIndex:0];
        NSMutableString *newString = [NSMutableString stringWithFormat:@"%@.%@",newstring,array[1]];
        return newString;
    }else {
        int count = 0;
        long long int a = num.longLongValue;
        while (a != 0)
        {
            count++;
            a /= 10;
        }
        NSMutableString *string = [NSMutableString stringWithString:num];
        NSMutableString *newstring = [NSMutableString string];
        while (count > 3) {
            count -= 3;
            NSRange rang = NSMakeRange(string.length - 3, 3);
            NSString *str = [string substringWithRange:rang];
            [newstring insertString:str atIndex:0];
            [newstring insertString:@"," atIndex:0];
            [string deleteCharactersInRange:rang];
        }
        [newstring insertString:string atIndex:0];
        return newstring;
    }
}

- (NSMutableAttributedString *)hlChangeStr:(NSString *)tragetStr toColor:(UIColor *)tragetColor {
    NSMutableAttributedString *att = [[NSMutableAttributedString alloc] initWithString:self];
    NSRange range = [att.mutableString rangeOfString:tragetStr];
    [att addAttribute:NSForegroundColorAttributeName value:tragetColor range:range];
    return  att;
}

- (NSDate *)toDate
{
    if (self.length == 10) {
        return [NSDate dateWithTimeIntervalSince1970:[self doubleValue]];
    }
    
    if (self.length == 13) {
        return [NSDate dateWithTimeIntervalSince1970:[self doubleValue]/1000];
    }
    
    return [NSDate date];
    
}
- (CGFloat)actualWidthWithFont:(UIFont *)font
{
    UILabel *label = [[UILabel alloc]init];
    label.text = self;
    label.font = font;
    CGFloat width = [label sizeThatFits:CGSizeZero].width;
    return width;
}
- (UIImage *)toQRCodeImageWithSize:(CGFloat)size
{
    if (!self) {
        return nil;
    }
    CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
    [filter setDefaults];
    NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];
    /*
     inputMessage,        //二维码输入信息
     inputCorrectionLevel //二维码错误的等级,就是容错率
     */
    [filter setValue:data forKeyPath:@"inputMessage"];
    
    CIImage *outImage = [filter outputImage];//这里拿到的图是小且模糊的
    
    // 处理图片让其更清楚
    CGRect extent = CGRectIntegral(outImage.extent);
    CGFloat scale = MIN(size / CGRectGetWidth(extent), size / CGRectGetHeight(extent));

    //1.创建bitmap;
    size_t width = CGRectGetWidth(extent) * scale;
    size_t height = CGRectGetHeight(extent) * scale;
    CGColorSpaceRef cs = CGColorSpaceCreateDeviceGray();
    CGContextRef bitmapRef = CGBitmapContextCreate(nil, width, height, 8, 0, cs, (CGBitmapInfo)kCGImageAlphaNone);
    CGColorSpaceRelease(cs);
    CIContext *context = [CIContext contextWithOptions:nil];
    CGImageRef bitmapImage = [context createCGImage:outImage fromRect:extent];
    CGContextSetInterpolationQuality(bitmapRef, kCGInterpolationNone);
    CGContextScaleCTM(bitmapRef, scale, scale);
    CGContextDrawImage(bitmapRef, extent, bitmapImage);

    //2.保存bitmap到图片
    CGImageRef scaledImage = CGBitmapContextCreateImage(bitmapRef);
    CGContextRelease(bitmapRef);
    CGImageRelease(bitmapImage);
    UIImage *image = [UIImage imageWithCGImage:scaledImage];
    CGImageRelease(scaledImage);
    return image;
}


//判断是否为整形：
- (BOOL)isPureInt
{
    NSScanner* scan = [NSScanner scannerWithString:self];
    NSInteger val;
    return[scan scanInteger:&val] && [scan isAtEnd];
}

//判断是否为浮点形：
- (BOOL)isPureFloat
{
    NSScanner* scan = [NSScanner scannerWithString:self];
    float val;
    return[scan scanFloat:&val] && [scan isAtEnd];
}

//从url中解析出参数表
- (NSDictionary*)parseURLParams {
    NSString* query = [self copy];
    NSRange range = [query rangeOfString:@"?"];
    if (range.length > 0) {
        query = [query substringFromIndex:range.location + 1];
    }
    NSArray* pairs = [query componentsSeparatedByString:@"&"];
    NSMutableDictionary* params = [[NSMutableDictionary alloc] init];
    for (NSString* pair in pairs) {
        NSArray* kv = [pair componentsSeparatedByString:@"="];
        if ([kv isKindOfClass:[NSArray class]] && kv.count == 2) {
            NSString* val = [kv[1]
                             stringByRemovingPercentEncoding];
            [params setObject:val forKey:kv[0]];
        }
    }
    return [params copy];
}
@end
